//
//  XUIGroupTableView.m
//  etionUI
//
//  Created by wjxfhxy on 15/12/24.
//  Copyright (c) 2015年 GuangZhouXuanWu. All rights reserved.
//

#import "XUIGroupTableView.h"

typedef NS_ENUM(NSInteger,XUIGroupTableViewCellType)
{
    XUIGroupTableViewCellTypeHeadSection,
    XUIGroupTableViewCellTypeRowCell
};

@implementation XUIGroupTableViewCell

-(instancetype)init
{
    self = [super initWithReuseIdentifier:@""];
    
    return self;
}

-(void)dealloc
{
    superdealloc_mm;
}

@end

@interface XUIGroupTableView()<XUITableViewDelegate,UITableViewDataSource>
{
    XUITableView *_tableView;
    
    NSMutableDictionary *_dicAllCells;
}

@end

@implementation XUIGroupTableView

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    
    self.backgroundColor = [[UITableView appearance] backgroundColor];
    
    _tableView = [[XUITableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain];
    _tableView.separatorExistFollowCell = YES;
    _tableView.delegate = self;
    _tableView.dataSource = self;
    _tableView.estimatedRowHeight = 0;
    [_tableView registerClass:[XUITableViewCell class] forCellReuseIdentifier:@"headCell"];
    [self addSubview:_tableView];
    
    if (@available(iOS 11.0, *))
        _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    
    _dicAllCells = [NSMutableDictionary new];
    
    return self;
}

-(void)dealloc
{
    [_tableView release_mm];
    [_dicAllCells release_mm];
    superdealloc_mm;
}

-(void)setFrame:(CGRect)frame
{
    super.frame = frame;
    
    _tableView.frame = self.bounds;
}

-(void)setContentInset:(UIEdgeInsets)contentInset
{
    _tableView.contentInset = contentInset;
    _tableView.scrollIndicatorInsets = contentInset;
}

-(void)setShowsVerticalScrollIndicator:(BOOL)showsVerticalScrollIndicator
{
    _tableView.showsVerticalScrollIndicator = showsVerticalScrollIndicator;
}

-(void)setScrollEnabled:(BOOL)scrollEnabled
{
    _tableView.scrollEnabled = scrollEnabled;
}

-(void)setContentSize:(CGSize)contentSize
{
    _tableView.contentSize = contentSize;
}

-(CGSize)contentSize
{
    return _tableView.contentSize;
}

-(BOOL)tracking
{
    return _tableView.tracking;
}

-(BOOL)dragging
{
    return _tableView.dragging;
}

-(BOOL)decelerating
{
    return _tableView.decelerating;
}

-(void)didMoveToSuperview
{
    [super didMoveToSuperview];
    
    if ([_tableView respondsToSelector:@selector(setSeparatorInset:)])
    {
        [_tableView setSeparatorInset:UIEdgeInsetsZero];
    }
    
#ifdef __IPHONE_8_0
    if ([_tableView respondsToSelector:@selector(setLayoutMargins:)])
    {
        [_tableView setLayoutMargins:UIEdgeInsetsZero];
    }
#endif
}

-(XUITableView*)getTableView
{
    return _tableView;
}

-(XUIGroupTableViewCellType)groupTableViewCellTypeForIndexPath:(NSIndexPath *)indexPath fixedIndexPath:(NSIndexPath**)fixedIndexPath
{
    XUIGroupTableViewCellType cellType = XUIGroupTableViewCellTypeHeadSection;
    
    NSUInteger row = indexPath.row;
    
    NSUInteger total = 0;
    NSUInteger groups = [_dataSource numberOfGroupsInGroupTableView:self];
    
    for(NSUInteger i = 0;i < groups; i++)
    {
        if(row == total)
        {
            cellType = XUIGroupTableViewCellTypeHeadSection;
            *fixedIndexPath = [NSIndexPath indexPathWithIndex:i];
            break;
        }
        else
        {
            total ++;
            NSUInteger r = [_dataSource groupTableView:self numberOfRowsInGroup:i];
            total += r;
            if(row < total)
            {
                cellType = XUIGroupTableViewCellTypeRowCell;
                *fixedIndexPath = [NSIndexPath indexPathForRow:r - (total - row) inSection:i];
                break;
            }
        }
    }
    return cellType;
}

-(NSArray*)tableViewIndexPathFromGroupTableViewIndexPath:(NSArray*)indexPaths
{
    NSMutableArray *array = [NSMutableArray new];
    
    for(NSIndexPath *indexPath in indexPaths)
    {
        NSUInteger total = 0;
        NSUInteger groups = [_dataSource numberOfGroupsInGroupTableView:self];
        for(NSUInteger group = 0;group < groups;group++)
        {
            total ++;
            if(group == indexPath.section)
            {
                NSIndexPath *i = [NSIndexPath indexPathForRow:total + indexPath.row inSection:0];
                [array addObject:i];
                break;
            }
            else
            {
                NSUInteger r = [_dataSource groupTableView:self numberOfRowsInGroup:group];
                total += r;
            }
        }
    }
    return array;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSUInteger groups = [_dataSource numberOfGroupsInGroupTableView:self];
    
    NSInteger rows = 0;
    
    for(NSUInteger i = 0;i < groups;i++)
    {
        rows += [_dataSource groupTableView:self numberOfRowsInGroup:i];
    }
    
    return groups + rows;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat height = 0;
    
    NSIndexPath *fixedIndexPath = nil;
    XUIGroupTableViewCellType cellType = [self groupTableViewCellTypeForIndexPath:indexPath fixedIndexPath:&fixedIndexPath];
    
    if(cellType == XUIGroupTableViewCellTypeHeadSection)
    {
        if([_delegate respondsToSelector:@selector(groupTableView:heightForHeaderInGroup:)])
        {
            height = [_delegate groupTableView:self heightForHeaderInGroup:fixedIndexPath.section];
            if(height <= -1)
                height = 20;
        }
        else
        {
            height = 20;
        }
    }
    else
    {
        height = [_delegate groupTableView:self heightForRowAtIndexPath:fixedIndexPath];
    }
    
    return height;
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    XUITableViewCell *cell = nil;
    
    NSIndexPath *fixedIndexPath = nil;
    XUIGroupTableViewCellType cellType = [self groupTableViewCellTypeForIndexPath:indexPath fixedIndexPath:&fixedIndexPath];
    
    if(cellType == XUIGroupTableViewCellTypeHeadSection)
    {
        cell = [tableView dequeueReusableCellWithIdentifier:@"headCell" forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.backgroundColor = [UIColor clearColor];
        [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
        if([_delegate respondsToSelector:@selector(groupTableView:viewForHeaderInGroup:)])
        {
            UIView *view = [_delegate groupTableView:self viewForHeaderInGroup:fixedIndexPath.section];
            if(view != nil)
                [cell.contentView addSubview:view];
        }
        if([_delegate respondsToSelector:@selector(groupTableView:hiddenHeaderSeparateLineInGroup:)])
        {
            BOOL hidden = [_delegate groupTableView:self hiddenHeaderSeparateLineInGroup:fixedIndexPath.section];
            cell.hiddenFollowSeparateLine = hidden;
        }
    }
    else
    {
        cell = _dicAllCells[fixedIndexPath];
        
        if(cell == nil)
        {
            cell = [_dataSource groupTableView:self cellForRowAtIndexPath:fixedIndexPath];
            _dicAllCells[fixedIndexPath] = cell;
        }
    }
    
    return cell;
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)])
    {
        UIEdgeInsets edge = [self tableView:(XUITableView*)tableView setSeparatorInsetForRowAtIndexPath:indexPath];
        [cell setSeparatorInset:edge];
    }
    
#ifdef __IPHONE_8_0
    if ([cell respondsToSelector:@selector(setLayoutMargins:)])
    {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
#endif
}

-(UIEdgeInsets)tableView:(XUITableView *)tableView setSeparatorInsetForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIEdgeInsets edgeInsets = UIEdgeInsetsZero;
    
    NSIndexPath *fixedIndexPath = nil;
    XUIGroupTableViewCellType cellType = [self groupTableViewCellTypeForIndexPath:indexPath fixedIndexPath:&fixedIndexPath];
    
    if(cellType == XUIGroupTableViewCellTypeHeadSection)
    {
        edgeInsets = UIEdgeInsetsZero;
    }
    else
    {
        if([_delegate respondsToSelector:@selector(groupTableView:setSeparatorInsetForRowAtIndexPath:)])
            edgeInsets = [_delegate groupTableView:self setSeparatorInsetForRowAtIndexPath:fixedIndexPath];
    }
    
    return edgeInsets;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    NSIndexPath *fixedIndexPath = nil;
    XUIGroupTableViewCellType cellType = [self groupTableViewCellTypeForIndexPath:indexPath fixedIndexPath:&fixedIndexPath];
    
    if(cellType == XUIGroupTableViewCellTypeHeadSection)
    {

    }
    else
    {
        if([_delegate respondsToSelector:@selector(groupTableView:didSelectRowAtIndexPath:)])
            [_delegate groupTableView:self didSelectRowAtIndexPath:fixedIndexPath];
    }
}

-(void)reloadData
{
    [_dicAllCells removeAllObjects];
    [_tableView reloadData];
}

-(void)insertRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(XUIGroupTableViewRowAnimation)animation
{
    NSArray *i = [self tableViewIndexPathFromGroupTableViewIndexPath:indexPaths];
    
//    NSArray *a = [[_dicAllCells allKeys] sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"section" ascending:YES],
//                                                         [NSSortDescriptor sortDescriptorWithKey:@"row" ascending:YES]]];
    NSArray *allKeys = [_dicAllCells allKeys];
    for(NSIndexPath *indexPath in indexPaths)
    {
        NSInteger maxRow = -1;
        for(NSIndexPath *key in allKeys)
        {
            if(indexPath.section == key.section)
            {
                maxRow = MAX(maxRow, key.row);
            }
        }
        if(maxRow != -1)
        {
            if(indexPath.row <= maxRow)
            {
                for(NSUInteger i = maxRow ;i>= indexPath.row;i--)
                {
                    _dicAllCells[[NSIndexPath indexPathForRow:i + 1 inSection:indexPath.section]] = _dicAllCells[[NSIndexPath indexPathForRow:i inSection:indexPath.section]];
                }
                [_dicAllCells removeObjectForKey:indexPath];
            }
        }
    }
    
    [_tableView insertRowsAtIndexPaths:i withRowAnimation:animation];
}

-(void)deleteRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(XUIGroupTableViewRowAnimation)animation
{
    NSArray *array = [self tableViewIndexPathFromGroupTableViewIndexPath:indexPaths];
    
    [_dicAllCells removeObjectsForKeys:indexPaths];
    
    NSArray *allKeys = [[_dicAllCells allKeys] sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"section" ascending:YES],
                                                                            [NSSortDescriptor sortDescriptorWithKey:@"row" ascending:YES]]];

    NSUInteger i = 0;
    NSUInteger j = 0;
    NSMutableDictionary *t = [[NSMutableDictionary new] autorelease_mm];
    for(NSIndexPath *indexPath in allKeys)
    {
        if(j != indexPath.section)
        {
            j = indexPath.section;
            i = 0;
        }
        t[[NSIndexPath indexPathForRow:i inSection:j]] = _dicAllCells[indexPath];
        i++;
    }
    
    [_dicAllCells removeAllObjects];
    [_dicAllCells addEntriesFromDictionary:t];
    
    [_tableView deleteRowsAtIndexPaths:array withRowAnimation:animation];
}

-(void)reloadRowsAtIndexPaths:(NSArray*)indexPaths withRowAnimation:(XUIGroupTableViewRowAnimation)animation
{
    [_dicAllCells removeObjectsForKeys:indexPaths];
    
    NSArray *array = [self tableViewIndexPathFromGroupTableViewIndexPath:indexPaths];
    
    [_tableView reloadRowsAtIndexPaths:array withRowAnimation:animation];
}

-(void)reloadSections:(NSIndexSet *)sections withRowAnimation:(XUIGroupTableViewRowAnimation)animation
{
    NSMutableArray *indexPaths = [NSMutableArray new];
    for(NSUInteger i = sections.firstIndex ;i <= sections.lastIndex;i++)
    {
        NSUInteger n = [_dataSource groupTableView:self numberOfRowsInGroup:i];
        for(NSUInteger j =0;j< n;j++)
        {
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:j inSection:i];
            [indexPaths addObject:indexPath];
        }
    }
    
    [self reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
}

-(void)beginUpdates
{
    [_tableView beginUpdates];
}

-(void)endUpdates
{
    [_tableView endUpdates];
}

-(XUIGroupTableViewCell*)cellWithTag:(NSString*)tag
{
    __block XUIGroupTableViewCell *cell = nil;
    [[_dicAllCells allValues] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
    {
        XUIGroupTableViewCell *c = obj;
        if([c.szTag isEqualToString:tag])
        {
            cell = obj;
            *stop = YES;
        }
    }];
    
    if(cell == nil)
    {
        if([_delegate respondsToSelector:@selector(groupTableView:findIndexPathWithTag:)])
        {
            NSIndexPath *indexPath = [_delegate groupTableView:self findIndexPathWithTag:tag];
            if(indexPath != nil)
            {
                cell = [_dataSource groupTableView:self cellForRowAtIndexPath:indexPath];
                _dicAllCells[indexPath] = cell;
            }
        }
    }
    
    return cell;
}

-(XUIGroupTableViewCell*)cellAtIndexPath:(NSIndexPath*)indexPath
{
    NSIndexPath *i = [self tableViewIndexPathFromGroupTableViewIndexPath:@[indexPath]][0];
    return (XUIGroupTableViewCell*)[_tableView cellForRowAtIndexPath:i];
}

-(NSIndexPath*)indexPathOfCell:(XUIGroupTableViewCell*)cell
{
    __block NSIndexPath *indexPath = nil;
    [_dicAllCells enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
    {
        if(obj == cell)
        {
            indexPath = key;
            *stop = YES;
        }
    }];
    return indexPath;
}

-(void)scrollToIndexPath:(NSIndexPath*)indexPath animated:(BOOL)animated
{
//    NSIndexPath *fixedIndexPath = nil;
//    [self groupTableViewCellTypeForIndexPath:indexPath fixedIndexPath:&fixedIndexPath];
    
    NSIndexPath *i = [self tableViewIndexPathFromGroupTableViewIndexPath:@[indexPath]][0];
    
    [_tableView scrollToRowAtIndexPath:i atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}

-(void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated
{
    [_tableView scrollRectToVisible:rect animated:animated];
}

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSIndexPath *fixedIndexPath = nil;
    XUIGroupTableViewCellType cellType = [self groupTableViewCellTypeForIndexPath:indexPath fixedIndexPath:&fixedIndexPath];
    
    if(cellType == XUIGroupTableViewCellTypeHeadSection)
    {
        return UITableViewCellEditingStyleNone;
    }
    else
    {
        if ([_delegate respondsToSelector:@selector(groupTableView:editingStyleForRowAtIndexPath:)]) {
            return [_delegate groupTableView:self editingStyleForRowAtIndexPath:fixedIndexPath];
        }
    }
    return UITableViewCellEditingStyleNone;
}

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSIndexPath *fixedIndexPath = nil;
    XUIGroupTableViewCellType cellType = [self groupTableViewCellTypeForIndexPath:indexPath fixedIndexPath:&fixedIndexPath];
    
    if(cellType == XUIGroupTableViewCellTypeHeadSection)
    {
        return NO;
    }
    else
    {
        if([_dataSource respondsToSelector:@selector(groupTableView:canEditRowAtIndexPath:)])
            return [_dataSource groupTableView:self canEditRowAtIndexPath:fixedIndexPath];
    }
    return NO;
}

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSIndexPath *fixedIndexPath = nil;
    XUIGroupTableViewCellType cellType = [self groupTableViewCellTypeForIndexPath:indexPath fixedIndexPath:&fixedIndexPath];
    
    if(cellType == XUIGroupTableViewCellTypeHeadSection)
    {
    }
    else
    {
        if ([_dataSource respondsToSelector:@selector(groupTableView:commitEditingStyle:forRowAtIndexPath:)]) {
            [_dataSource groupTableView:self commitEditingStyle:editingStyle forRowAtIndexPath:fixedIndexPath];
        }
    }
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    if([_delegate respondsToSelector:@selector(groupTableViewWillBeginDragging:)])
        [_delegate groupTableViewWillBeginDragging:self];
}
@end
